using System;
using System.IO;
using System.Collections.Generic;
using System.Text;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.VersionControl;
using Microsoft.TeamFoundation.VersionControl.Client;
using System.Xml;
using System.Xml.Serialization;
using System.Net;
using Ltf.Remoting.TeamFoundation;
using Microsoft.TeamFoundation.WorkItemTracking.Client;
using Ltf.Remoting.TFAccess;
//comment go here
namespace Ltf.Remoting.Commands
{
	

	public class ItemHistory
	{

		public static List<LizardChangeset> GetHistory(string filename)
		{
			return GetHistory(filename, false, 0, 200, RecursionType.Full);
		}

		public static List<LizardChangeset> GetHistory(string filename, bool includeWorkItems, int to, int maxCount)
		{
			return GetHistory(filename, false, to, maxCount, RecursionType.Full);

		}
		public static List<LizardChangeset> GetHistory(string filename, bool includeWorkItems
			, int to, int maxCount, RecursionType recursionType)
		{
			return GetHistory(filename, false, 1, to, maxCount, RecursionType.Full, null);

		}
		
		public static List<LizardChangeset> GetHistory(string filename, bool includeWorkItems
			, int from, int to, int maxCount, RecursionType recursionType, VersionControlServer versionControlServer)
		{
			object history;

			VersionSpec vsTo = (to == 0) ? ChangesetVersionSpec.Latest : new ChangesetVersionSpec(to);
			VersionSpec vsFrom = (from == 0) ? ChangesetVersionSpec.Latest : new ChangesetVersionSpec(from);
			VersionControlServer vcs = null;
			if (!filename.StartsWith("$"))
				vcs = ServerConnections.GetConnectionForPath(filename).VersionControlServer;
			else if (versionControlServer != null)
				vcs = versionControlServer;
			else
				throw new ArgumentException("Version Control Server can not be null for server paths");

			history = vcs.QueryHistory(filename, LatestVersionSpec.Latest, 0,
				recursionType, "", vsFrom, vsTo, maxCount, true, false);

			System.Collections.IEnumerable changesets = (System.Collections.IEnumerable)history;
			StringBuilder sb = new StringBuilder();
			List<LizardChangeset> changes = new List<LizardChangeset>();
			try
			{
				foreach (Changeset c in changesets)
				{
					string notes = string.Empty;
					List<LizardChange> details = new List<LizardChange>();
					foreach (Change ch in c.Changes)
					{
						LizardChange lc = new LizardChange();
						lc.ChangeType = ch.ChangeType.ToString();
						lc.ServerItem = ch.Item.ServerItem;
						lc.ItemId = ch.Item.ItemId;
						lc.ChangesetId = ch.Item.ChangesetId;
						lc.IsRename = ((ch.ChangeType & ChangeType.Rename) == ChangeType.Rename);
						details.Add(lc);
					}
					foreach (CheckinNoteFieldValue cnfv in c.CheckinNote.Values)
					{
						notes += ((notes == string.Empty) ? "" : ", ") + string.Format("{0} = {1}",cnfv.Name, cnfv.Value);
					}
					LizardChangeset lcs = new LizardChangeset();
					lcs.Changes = details.ToArray();
					lcs.ChangesetId = c.ChangesetId;
					lcs.CreationDate = c.CreationDate;
					lcs.Commiter = c.Committer;
					lcs.Comment = c.Comment;
					lcs.CheckinNote = notes;
					changes.Add(lcs);
					if (includeWorkItems)
					{
						List<string> workItemIds = new List<string>();
						foreach (WorkItem wi in c.WorkItems)
						{
							workItemIds.Add(wi.Id.ToString());
						}
						lcs.WorkItemIds = string.Join(",", workItemIds.ToArray());
					}
				}
			}
			catch
			{
				// no history, probably a new item.
			}
			return changes;
		}

		public static Changeset GetChangesetDetails(TFServerConnection connection, int changesetId)
		{
			VersionControlServer vcs = connection.VersionControlServer;
			Changeset c = vcs.GetChangeset(changesetId);
			return c;
		}

		public static int GetPreviousRevisionId(string path, VersionSpec versionSpec)
		{
			object history;
			VersionControlServer vcs = ServerConnections.GetConnectionForPath(path).VersionControlServer;
			history = vcs.QueryHistory(path, LatestVersionSpec.Latest, 0,
				RecursionType.Full, "", new ChangesetVersionSpec(1),
				versionSpec, 2, false, false);
			int previous = 0;
			System.Collections.IEnumerable changesets = (System.Collections.IEnumerable)history;
			foreach (Changeset c in changesets)
			{
				previous = c.ChangesetId;
			}
			return previous;
		}

		public static int GetServerLatest(string path, VersionSpec versionSpec)
		{
			int v = 0;
			int deletionId = 0;
			string name = string.Empty;
			LizardFileAccess.GetNameAndVersionFromPath(path, out name, out v, out deletionId);
			object history;
			VersionControlServer vcs = ServerConnections.GetConnectionForPath(path).VersionControlServer;
			history = vcs.QueryHistory(path, LatestVersionSpec.Latest, deletionId,
				RecursionType.Full, "", new ChangesetVersionSpec(1),
				versionSpec, 1, false, false);
			int latest = 0;
			System.Collections.IEnumerable changesets = (System.Collections.IEnumerable)history;
			foreach (Changeset c in changesets)
			{
				latest = c.ChangesetId;
			}
			return latest;
		}

		public static int GetBranchHistory(string path, VersionSpec versionSpec, ref string fromPath)
		{
			VersionControlServer vcs = ServerConnections.GetConnectionForPath(path).VersionControlServer;
			BranchHistoryTreeItem[] bhti = vcs.GetBranchHistory(new ItemSpec[] { new ItemSpec(path, RecursionType.Full) }, versionSpec)[0];
			fromPath = string.Empty;
			int postBranchChangeSet = 0;
			string matchPath = vcs.GetWorkspace(path).GetServerItemForLocalItem(path);
			foreach (BranchHistoryTreeItem ti in bhti)
			{
				postBranchChangeSet = GetMaxBranchChangeSet(matchPath, ti, 0, ref fromPath);
			}
			return postBranchChangeSet;
		}

		private static int GetMaxBranchChangeSet(string matchPath, BranchHistoryTreeItem treeItem, int currentMax, ref string fromPath)
		{
			Item relToItem = treeItem.Relative.BranchToItem;
			Item relFromItem = treeItem.Relative.BranchFromItem;
			if (relFromItem!=null && relToItem.ServerItem.StartsWith(matchPath) && relFromItem.ChangesetId > currentMax)
			{
				currentMax = relFromItem.ChangesetId;
				if (relFromItem.ServerItem.Split('/').Length <= fromPath.Split('/').Length || fromPath==string.Empty)
					fromPath = relFromItem.ServerItem;
			}

			foreach (BranchHistoryTreeItem child in treeItem.Children)
			
				currentMax = GetMaxBranchChangeSet(matchPath, child, currentMax, ref fromPath);

			return currentMax;
		}

	}
}
